package com.cndym.utils.hibernate;

import org.hibernate.*;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

public class HibernateUtil extends HibernateDaoSupport {
    public List findList(final String select, final Object paramValues[]) {
        return getTemplate().executeFind(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(select);
                if (null != paramValues) {
                    for (int i = 0; i < paramValues.length; i++) {
                        query.setParameter(i, paramValues[i]);
                    }
                }
                List list = query.list();
                return list;
            }
        });
    }

    private HibernateTemplate getTemplate() {
        return getHibernateTemplate();
    }

    public boolean updateObject(Object object) {
        getTemplate().update(object);
        return true;
    }

    public boolean deleteObject(Object object) {
        getTemplate().delete(object);
        return true;
    }

    public boolean mergeObject(Object object) {
        getTemplate().merge(object);
        return true;
    }

    public boolean saveObject(Object object) {
        getTemplate().save(object);
        return true;
    }

    public boolean saveAllObject(List object) {
        getTemplate().saveOrUpdateAll(object);
        return true;
    }

    public Object load(Class c, Serializable id) {
        return getTemplate().load(c, id);
    }

    public int getPageTotal(final String select, final Object paramValues[], final int pageSize) {
        String sql = select.toUpperCase();
        int start = sql.indexOf("FROM");
        int end = sql.indexOf(" ORDER BY");
        if (end < 0) {
            end = sql.length();
        }
        final String countSql = "select count(*) " + select.substring(start, end);
        return (Integer) getTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(countSql);
                if (null != paramValues) {
                    for (int i = 0; i < paramValues.length; i++) {
                        query.setParameter(i, paramValues[i]);
                    }
                }
                Long longValue = (Long) query.uniqueResult();
                session.close();
                int count = longValue.intValue();
                if (count % pageSize == 0) {
                    return count / pageSize;
                } else {
                    return count / pageSize + 1;
                }
            }
        });
    }

    public String getPageTotalItem(final String select, final Object paramValues[], final int pageSize) {
        String sql = select.toUpperCase();
        int start = sql.indexOf("FROM");
        int end = sql.indexOf(" ORDER BY");
        if (end < 0) {
            end = sql.length();
        }
        final String countSql = "select count(*) " + select.substring(start, end);
        return (String) getTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(countSql);
                if (null != paramValues) {
                    for (int i = 0; i < paramValues.length; i++) {
                        query.setParameter(i, paramValues[i]);
                    }
                }
                Long longValue = (Long) query.uniqueResult();
                session.close();
                int count = longValue.intValue();
                if (count % pageSize == 0) {
                    return count / pageSize + "," + longValue;
                } else {
                    return count / pageSize + 1 + "," + longValue;
                }
            }
        });
    }

    public PageBean getPageBean(final String select, final Object paramValues[], int pageId, final int pageSize) {
        String[] tempArr = getPageTotalItem(select, paramValues, pageSize).split(",");
        int pageTotal = Integer.parseInt(tempArr[0]);
        if (pageId <= 1) {
            pageId = 1;
        }
        if (pageId > pageTotal) {
            pageId = pageTotal;
        }
        if (pageTotal <= 0) {
            pageId = 1;
            pageTotal = 0;
        }
        final int start = (pageId - 1) * pageSize;
        List pageContent = getTemplate().executeFind(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(select);
                if (null != paramValues) {
                    for (int i = 0; i < paramValues.length; i++) {
                        query.setParameter(i, paramValues[i]);
                    }
                }
                query.setFirstResult(start);
                query.setMaxResults(pageSize);
                return query.list();
            }
        });
        PageBean pageBean = new PageBean();
        pageBean.setPageId(pageId);
        pageBean.setPageTotal(pageTotal);
        pageBean.setPageContent(pageContent);
        pageBean.setItemTotal(Long.parseLong(tempArr[1]));
        return pageBean;
    }
    
    public PageBean getPageBean2(final String select, final Object paramValues[], int pageId, final int pageSize) {
//        String[] tempArr = getPageTotalItem(select, paramValues, pageSize).split(",");
//        int pageTotal = Integer.parseInt(tempArr[0]);
//        if (pageId <= 1) {
//            pageId = 1;
//        }
//        if (pageId > pageTotal) {
//            pageId = pageTotal;
//        }
//        if (pageTotal <= 0) {
//            pageId = 1;
//            pageTotal = 0;
//        }
//        final int start = (pageId - 1) * pageSize;
        List pageContent = getTemplate().executeFind(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(select);
                if (null != paramValues) {
                    for (int i = 0; i < paramValues.length; i++) {
                        query.setParameter(i, paramValues[i]);
                    }
                }
                query.setFirstResult(0);
                query.setMaxResults(pageSize);
                return query.list();
            }
        });
        PageBean pageBean = new PageBean();
        pageBean.setPageId(pageId);
        pageBean.setPageTotal(100);
        pageBean.setPageContent(pageContent);
        pageBean.setItemTotal(100l);
        return pageBean;
    }

    public List findList(final String select, final List<HibernatePara> para) {
        return getTemplate().executeFind(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(select);
                if (null != para) {
                    for (int i = 0; i < para.size(); i++) {
                        if ("Date".equals(para.get(i).getType())) {
                            query.setTimestamp(i, (Date) para.get(i).getValue());
                        } else {
                            query.setParameter(i, para.get(i).getValue());
                        }
                    }
                }
                List list = query.list();
                return list;
            }
        });
    }

    public List findSqlList(final String select) {
        return getTemplate().executeFind(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                SQLQuery query = session.createSQLQuery(select);
                query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
                return query.list();
            }
        });
    }

    public String getPageTotal(final String select, final List<HibernatePara> para, final int pageSize) {
        String sql = select.toUpperCase();
        int start = sql.indexOf("FROM");
        int end = sql.indexOf(" ORDER BY");
        if (end < 0) {
            end = sql.length();
        }
        final String countSql = "select count(*) " + select.substring(start, end);
        return (String) getTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(countSql);
                if (null != para) {
                    for (int i = 0; i < para.size(); i++) {
                        if ("Date".equals(para.get(i).getType())) {
                            query.setTimestamp(i, (Date) para.get(i).getValue());
                        } else {
                            query.setParameter(i, para.get(i).getValue());
                        }
                    }
                }
                Long longValue = (Long) query.uniqueResult();
                session.close();
                int count = longValue.intValue();
                if (count % pageSize == 0) {
                    return (count / pageSize) + "," + longValue;
                } else {
                    return (count / pageSize + 1) + "," + longValue;
                }
            }
        });
    }

    public PageBean getPageBeanByPara(final String select, final List<HibernatePara> para, int pageId, final int pageSize) {
        String[] tempArr = getPageTotal(select, para, pageSize).split(",");
        int pageTotal = Integer.parseInt(tempArr[0]);
        if (pageId <= 1) {
            pageId = 1;
        }
        if (pageId > pageTotal) {
            pageId = pageTotal;
        }
        if (pageTotal <= 0) {
            pageId = 1;
            pageTotal = 0;
        }
        final int start = (pageId - 1) * pageSize;
        List pageContent = getTemplate().executeFind(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                Query query = session.createQuery(select);
                if (null != para) {
                    for (int i = 0; i < para.size(); i++) {
                        if ("Date".equals(para.get(i).getType())) {
                            query.setTimestamp(i, (Date) para.get(i).getValue());
                        } else {
                            query.setParameter(i, para.get(i).getValue());
                        }
                    }
                }
                query.setFirstResult(start);
                query.setMaxResults(pageSize);
                return query.list();
            }
        });
        PageBean pageBean = new PageBean();
        pageBean.setPageId(pageId);
        pageBean.setPageTotal(pageTotal);
        pageBean.setPageContent(pageContent);
        pageBean.setItemTotal(Long.parseLong(tempArr[1]));
        return pageBean;
    }

    public PageBean dynamicQueryObject(Object object, int pageId, int pageSize) {
        try {
            String select = HqlMaker.makeHql(object);
            return getPageBean(select, new Object[]{}, pageId, pageSize);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public boolean saveOrUpdateObject(Object object) {
        getTemplate().saveOrUpdate(object);
        return true;
    }
}
